package com.topisv.tms.service.md;

import java.io.StringReader;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.DataBindingException;
import javax.xml.bind.JAXB;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.topisv.tms.entity.EdiOrder;
import com.topisv.tms.entity.stock.instorage.pre.InstorageBillPre;
import com.topisv.tms.exception.ErrorCode;
import com.topisv.tms.exception.PaiUException;
import com.topisv.tms.repository.EdiOrderDao;
import com.topisv.tms.repository.stock.preInstorage.InstorageBillPreDao;
import com.topisv.tms.rest.entity.md.request.TransferBodyContent;
import com.topisv.tms.rest.entity.md.request.TransferData;
import com.topisv.tms.rest.entity.md.request.TransferSubject;
import com.topisv.tms.rest.entity.md.response.Response;
import com.topisv.tms.service.vo.invoice.MDParam;
import com.topisv.tms.tools.TransferHelper;
import com.topisv.tms.utils.WmsContants;
import com.topisv.tms.utils.enums.MDOrderType;

/**
 * 美的接口的公用抽象类
 *  Date          Author       Version       Description
 * ----------------------------------------------------------
 *  2015-1-8      CC            1.0           Create
 */
@Component
public class MdBusinessExecutor {
	protected Logger logger = LoggerFactory.getLogger(getClass());
	private static final Logger mdOrderLogger = LoggerFactory.getLogger("AnntoOrder");
	@Autowired
	private InstorageBillPreDao instorageBillPreDao;
	@Autowired
	private EdiOrderDao ediOrderDao;

	protected void check(TransferData transferData) throws PaiUException {
		TransferSubject subject = transferData.getTransferSubject();
		if (subject == null) {
			throw new PaiUException(ErrorCode.XML_ERROR);
		}
		TransferBodyContent bodyContent = TransferHelper.getTransferBodyContent(transferData);
		if (bodyContent == null) {
			throw new PaiUException(ErrorCode.XML_ERROR);
		}
		if (!MDParam.MD_NAME.equals(subject.getSender())) {
			throw new PaiUException(ErrorCode.SENDER_ERROR);
		}
		if (!MDParam.PAIU_NAME.equals(subject.getReceiver())) {
			throw new PaiUException(ErrorCode.RECEIVER_ERROR);
		}

		String orderType = bodyContent.getOrderType();
		String custOrdNo = bodyContent.getCustOrdNo();
		if (MDOrderType.SALE.getType().equals(orderType)) {
			if (StringUtils.isBlank(custOrdNo)) {
				throw new PaiUException(ErrorCode.FIELD_ERROR, new String[] { "custOrdNo" });
			}
			List<EdiOrder> orders = ediOrderDao.findByCustomerCodeAndCustomerOrdeno(WmsContants.CUSTOMER_MID, custOrdNo);
			if (!orders.isEmpty()) {
				throw new PaiUException(ErrorCode.ORDER_REPEAT_ERROR, new String[] { custOrdNo });
			}
		}else if (MDOrderType.REBACK.getType().equals(orderType)) {
			if (StringUtils.isBlank(custOrdNo)) {
				throw new PaiUException(ErrorCode.FIELD_ERROR, new String[] { "custOrdNo" });
			}
			List<EdiOrder> orders = ediOrderDao.findByCustomerCodeAndCustomerOrdeno(WmsContants.CUSTOMER_MID, custOrdNo);
			if (!orders.isEmpty()) {
				throw new PaiUException(ErrorCode.ORDER_REPEAT_ERROR, new String[] { custOrdNo });
			}
		} else if (MDOrderType.PURCHASE.getType().equals(orderType)) {
			if (StringUtils.isBlank(custOrdNo)) {
				throw new PaiUException(ErrorCode.FIELD_ERROR, new String[] { "custOrdNo" });
			}
			InstorageBillPre billPre = instorageBillPreDao.findByCustomerCodeAndCustomerOrderNo(WmsContants.CUSTOMER_MID, custOrdNo);
			if (billPre != null) {
				throw new PaiUException(ErrorCode.ORDER_REPEAT_ERROR, new String[] { custOrdNo });
			}
		} else if (MDOrderType.RETURN.getType().equals(orderType)) {
			if (StringUtils.isBlank(custOrdNo)) {
				throw new PaiUException(ErrorCode.FIELD_ERROR, new String[] { "custOrdNo" });
			}
			InstorageBillPre billPre = instorageBillPreDao.findByCustomerCodeAndCustomerOrderNo(WmsContants.CUSTOMER_MID, custOrdNo);
			if (billPre != null) {
				throw new PaiUException(ErrorCode.ORDER_REPEAT_ERROR, new String[] { custOrdNo });
			}
		} else if (MDOrderType.CHECKIN.getType().equals(orderType)
				||MDOrderType.CHECKOUT.getType().equals(orderType)) {
			if (StringUtils.isBlank(custOrdNo)) {
				throw new PaiUException(ErrorCode.FIELD_ERROR, new String[] { "custOrdNo" });
			}
			InstorageBillPre billPre = instorageBillPreDao.findByCustomerCodeAndCustomerOrderNo(WmsContants.CUSTOMER_MID, custOrdNo);
			if (billPre != null) {
				throw new PaiUException(ErrorCode.ORDER_REPEAT_ERROR, new String[] { custOrdNo });
			}
		} else {
			throw new PaiUException(ErrorCode.ORDER_TYPE_UNDEFIND_ERROR, new String[] { custOrdNo });
		}
	}

	@Transactional(readOnly = false)
	public void messageReceiverExecutor(HttpServletRequest request, MdCallBack callBack) throws Exception {
		logger.info("a new midea request begin");
		try {
			String xml = IOUtils.toString(request.getInputStream(),"UTF-8");
			mdOrderLogger.info(xml);
			TransferData transferData = JAXB.unmarshal(new StringReader(xml), TransferData.class);
			// 1.验证
			check(transferData);
			// 2.执行业务逻辑
			Response response = callBack.doBusiness(transferData);
			// 3.返回给客户端的代码
			callBack.doResponse(response);
		} catch (DataBindingException e) {
			throw new PaiUException(ErrorCode.XML_ERROR, e);
		} catch (PaiUException e) {
			//如果重复的订单，返回true
			if (ErrorCode.ORDER_REPEAT_ERROR.getCode().equals(e.getErrorCode())) {
				Response response = new Response();
				response.setFlag(true);
				callBack.doResponse(response);
			} else {
				throw e;
			}
		} catch (Exception e) {
			throw new PaiUException(ErrorCode.DATA_ERROR, e);
		}
		logger.info("a new midea request end");
	}

}
